# -*- mode: python; coding: utf-8; -*-
##--------------------------------------------------------------------------##
##
## Copyright (C) 1998-2003 Markus Oberhumer <markus@oberhumer.com>
## Copyright (C) 2003 Mt. Hood Playing Card Co.
## Copyright (C) 2005-2010 Skomoroh <skomoroh@users.sourceforge.net>
## Copyright (C) 2010-2013 Jeremy Austin-Bardo <tjaustinbardo@gmail.com>
##
## This program is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program.  If not, see <http://www.gnu.org/licenses/>.
##
##--------------------------------------------------------------------------##
__docformat__ = "restructuredtext en"

import logging

Logger = logging.getLogger('PySolFC.GameShisensho')

from ... import autostacks
from ... import formlib as layout
from ... import pilelib as stack
from ...animation import draw_hint_path
from ...gamelib import state, game
from ...piles import shisensho as sstack
from ...settings import CONF_OPT


class AbstractShisenGame(game.Game):

    _talon_ = stack.InitialDealTalon
    _foundation_ = stack.SingleFoundation
    _row_ = sstack.RowStack
    _hint_ = sstack.Shisen_Hint
    _hint_item_ = draw_hint_path

    def _create_game(self, size=(18, 8,), **kw):
        l, s = layout.Layout(self), self.s
        cols, rows = size
        assert cols * rows == l.NCARDS
        self.table_size = (l.XM + 3 + cols * l.CW + l.XM + 80 + l.XM,
                     l.YM + 3 + rows * l.CH + l.YM)
        self.check_dist = l.CW ** 2 + l.CH ** 2
        self.cols = [[]] * cols
        for col in range(cols):
            for row in range(rows):
                x, y = l.XM + 3 + col * l.CW, l.YM + 3 + row * l.CW
                s['rows'].append(self._row_(x, y, game=self, offset=(0, 0)))
                s['rows'][-1].position = col, row
                self.cols[col].append(s['rows'][-1])
        coords = self.canvas.get_hidden_coords(self.images.size)
        s['foundations'].append(self._foundation_(coords.x, coords.y,
                                               game=self))
        self.texts['info'] = l.create_info_text(None, anchor='nw',
                                             dx=self.width - l.XM, dy=y)
        s['talon'] = self._talon_(x, self.height - 3, game=self)
        l.defaultStackGroups()

    def _start(self, **kw):
        """
        Deal initial cards for new game.
          - s[rows] 1 ea.

        .. \_start([]) -> None
        """
        self.s['talon'].dealRow(rows=self.s['rows'][:-12], frames=0)
        self.s['talon'].dealRow(rows=self.s['rows'][-12:])

    @state.move_state('fill')
    def _auto_fill(self, stack):
        """
        Move tiles down to fill empty `s.rows`.
        """
        to_stack = stack
        col, row = stack.position
        for from_stack in (s for s in self.cols[col][row + 1::-1] if s.cards):
            from_stack.move_pile(1, to_stack, frames=0)
            to_stack = from_stack

    @state.not_state('is_preview')
    def _update_text(self):
        """
        _update_text() -> None

        Show tiles removed and tiles remaining. When 'shisen_show_matching'
        also include free matching pairs count.
        """
        if not self.texts['info']:
            return

        text = ''
        if CONF_OPT['shisen_show_matching']:
            stacks = self.s['rows']
            pairs = 0
            for from_stack in stacks[::2]:  # odd piles
                for to_stack in stacks[1::2]:  # even piles
                    if to_stack.cardsBuild(from_stack, from_stack.cards):
                        pairs += 1
            if pairs == 0:
                text = _('No Free\nMatching\nPairs')
            else:
                text = p_.ngettext('%d Free\nMatching\nPair',
                                    '%d Free\nMatching\nPairs', pairs) % pairs

        ncards = self['ncards']
        drop = len(self.s['foundations'][0].cards)
        r1 = p_.ngettext('%d\nTile\nRemoved\n\n',
                          '%d\nTiles\nRemoved\n\n', drop) % drop
        r2 = p_.ngettext('%d\nTile\nRemaining\n\n',
                          '%d\nTiles\nRemaining\n\n',
                           ncards - drop) % (ncards - drop)
        self.texts['info'].config(text=text + r1 + r2)

    @property
    def _highlight_piles(self):
        """
        Return piles to highlight for possible move.

        :return: `s.rows` >= 1.
        :rtype: tuple
        """
        return (self.s['rows'], 1)

    def _autopiles(self, event=None):
        """
        Return piles for auto or quick move.

        Overide to disable autoflip, autodrop, quickplay.

        .. \_autopiles(self, event=None) -> seq(seq(Pile ...), seq(Pile ...),
             seq(Pile ...))
        """
        return autostacks.none()